package io.renren.modules.netty.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.renren.modules.netty.model.ElecmeterMessageHeader;
import io.renren.modules.netty.model.ElecmeterMessageObj;
import io.renren.util.CommonUtil;
import io.renren.util.HexUtils;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import java.util.List;

@Slf4j
public class SocketDecoder extends ByteToMessageDecoder {

  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> list) throws Exception {
    try {
      buffer.markReaderIndex();
      // 防止socket字节流攻击
      // 防止，客户端传来的数据过大
      // 因为，太大的数据，是不合理的
      if (buffer.readableBytes() > 2048) {
        buffer.skipBytes(buffer.readableBytes());
      }
      byte[] bs = new byte[buffer.readableBytes()];
      buffer.readBytes(bs);
      if (bs.length < 12) {
        return;
      }
      log.info("read string is " + HexUtils.bytesToHexString(bs));
      String xmlStr = decode(bs);
      xmlStr = xmlStr.substring(0, xmlStr.indexOf("</root>") + 7);
      log.info("read xml is " + xmlStr);
      byte[] serializ = HexUtils.getByteArrayByLength(bs, 8, 4);
      ElecmeterMessageHeader header = new ElecmeterMessageHeader(serializ);
      ElecmeterMessageObj message = new ElecmeterMessageObj(header, xmlStr);
      list.add(message);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
    }
  }
  public String decode(byte[] content) {
    try {
      byte[] lengthByte = HexUtils.getByteArrayByLength(content, 4, 4);
      int length = HexUtils.byteToInt_HL(lengthByte, 0);
      byte[] encodedContent = HexUtils.getByteArrayByLength(content, 12, length - 4);
      Cipher cipher = CommonUtil.getCipher(Cipher.DECRYPT_MODE);
      byte[] decodeContent = cipher.doFinal(encodedContent);
      return new String(decodeContent);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
    }
    return null;
  }
}
